package com.learn.framework.exception;

import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.web.ErrorAttributes;
import org.springframework.boot.autoconfigure.web.ErrorController;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.http.HttpStatus;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.Map;
import org.slf4j.Logger;

@Controller
public class AppErrorController implements ErrorController {
    private static final Logger logger = LoggerFactory.getLogger(AppErrorController.class);

    private final static String ERROR_PATH = "/error";
    @Autowired
    private ErrorAttributes errorAttributes;
    @Override
    public String getErrorPath() {
        return ERROR_PATH;
    }

    @RequestMapping(value = ERROR_PATH)
    public String errorHtml(HttpServletRequest request, Model model) {

        Map<String, Object> errorInfo   =   getErrorAttributes(request, true);
        String trace    =   (String)errorInfo.get("trace");
        String file = "", line = "0", errorMessage = "";
        if(trace!=null && !trace.equals("")){
            String[] traceList      =   trace.split("\n\t");
            String[] fileAndLine    =   traceList[1].split(":");
            file                    =   fileAndLine[0];
            line                    =   fileAndLine[1];
            errorMessage            =   traceList[0];
        }

        model.addAttribute("status", errorInfo.get("status"));
        model.addAttribute("URL", errorInfo.get("URL"));
        model.addAttribute("path", errorInfo.get("path"));
        model.addAttribute("file", file);
        model.addAttribute("line", line);
        model.addAttribute("error", errorInfo.get("error"));
        model.addAttribute("message", errorMessage);
        Date time   =   (Date)errorInfo.get("timestamp");
        model.addAttribute("timestamp", time);
        model.addAttribute("trace", errorInfo.get("trace"));
        return "exception/debug";
    }

    private boolean getTraceParameter(HttpServletRequest request) {
        String parameter = request.getParameter("trace");
        if (parameter == null) {
            return false;
        }
        return !"false".equals(parameter.toLowerCase());
    }

    private Map<String, Object> getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) {
        RequestAttributes requestAttributes = new ServletRequestAttributes(request);
        Map<String, Object> map = this.errorAttributes.getErrorAttributes(requestAttributes,includeStackTrace);
        String URL = request.getRequestURL().toString();
        map.put("URL", URL);
        return map;
    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer statusCode = (Integer) request
                .getAttribute("javax.servlet.error.status_code");
        if (statusCode != null) {
            try {
                return HttpStatus.valueOf(statusCode);
            }
            catch (Exception ex) {
            }
        }
        return HttpStatus.INTERNAL_SERVER_ERROR;
    }
}
